package com.zyf.project.binaryproto.encoder.impl.dynamic;

import com.zyf.project.binaryproto.converter.DynamicValueConverter;
import com.zyf.project.binaryproto.encoder.impl.DynamicArrayFieldEncoder;
import com.zyf.project.binaryproto.specification.BinarySliceSpecification;
import com.zyf.project.binaryproto.specification.FieldSpecification;
import org.jetbrains.annotations.NotNull;
import utils.binary.BytesSlices;
import utils.binary.impl.BytesSlice;
import utils.binary.io.BytesOutputBuffer;
import utils.io.NumberMask;

import java.lang.reflect.Method;

/**
 * <p>字节数组编码器</p>
 * <p>针对可转换为原生类型 byte[] 数组的字段类型的编码器</p>
 * <p>继承了 {@link DynamicArrayFieldEncoder}</p>
 *
 * @author Zhou Yifan
 */
public class DynamicByteArrayFieldEncoder extends DynamicArrayFieldEncoder {

    public static final byte[] EMPTY_VALUES = {};

    public DynamicByteArrayFieldEncoder(
            BinarySliceSpecification binarySliceSpecification,
            FieldSpecification fieldSpecification,
            Method reader,
            DynamicValueConverter valueConverter) {
        super(binarySliceSpecification, fieldSpecification, reader, valueConverter);
    }

    @Override
    protected int encodeArrayDynamic(Object values, @NotNull BytesOutputBuffer buffer) {
        int size = 0;

        byte[] valuesArray = values == null ? EMPTY_VALUES : (byte[]) values;
        int count = valuesArray.length;
        byte[] countBytes = NumberMask.NORMAL.generateMask(count);
        buffer.write(countBytes);
        size += countBytes.length;

        for (byte b : valuesArray) {
            size += valueConverter.encode(b, buffer);
        }

        return size;
    }

    @Override
    public byte[] decodeField(BytesSlices fieldBytes) {
        int fieldCount = null != fieldBytes ? fieldBytes.getCount() : 0;
        byte[] values = new byte[fieldCount];
        BytesSlice itemSlice;
        for (int i = 0; i < fieldCount; i++) {
            itemSlice = fieldBytes.getDataSlice(i);
            if (itemSlice.getSize() == 0) {
                values[i] = 0;
            } else {
                values[i] = itemSlice.getByte();
            }
        }
        return values;
    }

}
